/*
 * Copyleft 2011 Power by Colen.
 *
 * Project: booking
 * Date: Jul 2, 2011
 */
package com.app.platform.base.dao;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.apache.log4j.Logger;
import org.springframework.jdbc.core.simple.SimpleJdbcDaoSupport;

import com.app.platform.base.utils.BeanUtil;
import com.app.platform.base.utils.ConvertUtil;

/**
 * Simple DAO Support
 *
 * @author Colen
 *
 */
public class SimpleDaoSupportEx extends SimpleJdbcDaoSupport {


    /** Logger */
    private static Logger logger = Logger.getLogger(SimpleDaoSupportEx.class);

    /**
     * Query For Map
     *
     * @param sql SQL
     * @param args Arguments
     * @return Map
     */
    @SuppressWarnings("rawtypes")
    public Map queryForMap(String sql, Object... args) {
        Map m = getSimpleJdbcTemplate().queryForMap(sql, args);
        ConvertUtil.lowerMapkeys(m);
        return m;
    }

    /**
     * Query For Map
     *
     * @param sql SQL
     * @param args Arguments
     * @return Map
     */
    @SuppressWarnings({ "rawtypes", "unchecked" })
    public Map queryForMap(String sql, Map args) {
        Map m = getSimpleJdbcTemplate().queryForMap(sql, args);
        ConvertUtil.lowerMapkeys(m);
        return m;
    }

    /**
     * Query For Long.
     *
     * @param sql SQL
     * @param args Arguments
     * @return long value
     */
    @SuppressWarnings({ "rawtypes", "unchecked" })
    public long queryForLong(String sql, Map args) {
        return getSimpleJdbcTemplate().queryForLong(sql, args);
    }


    /**
     * Query for Long.
     *
     * @param sql SQL
     * @param args Arguments
     * @return long value.
     */
    public long queryForLong(String sql, Object... args) {
        return getSimpleJdbcTemplate().queryForLong(sql, args);
    }


    /**
     * Query For Object.
     *
     * @param sql SQL
     * @param type Class
     * @param args Arguments
     * @return Object.
     */
    @SuppressWarnings({ "rawtypes", "unchecked" })
    public Object queryForObject(String sql, Class type, Object... args) {
        return getSimpleJdbcTemplate().queryForObject(sql, type, args);
    }


    /**
     * Query for Object.
     *
     * @param sql SQL
     * @param type Class
     * @param args Arguments
     * @return Object.
     */
    @SuppressWarnings({ "rawtypes", "unchecked" })
    public Object queryForObject(String sql, Class type, Map args) {
        return getSimpleJdbcTemplate().queryForObject(sql, type, args);
    }


    /**
     * Query For Integer
     *
     * @param sql SQL
     * @param args Arguments
     * @return integer.
     */
    @SuppressWarnings({ "rawtypes", "unchecked" })
    public int queryForInt(String sql, Map args) {
        return getSimpleJdbcTemplate().queryForInt(sql, args);
    }


    /**
     * Query For Integer
     *
     * @param sql SQL
     * @param args Arguments
     * @return integer.
     */
    public int queryForInt(String sql, Object... args) {
        return getSimpleJdbcTemplate().queryForInt(sql, args);
    }


    /**
     * Update Table
     *
     * @param sql SQL
     * @param args Arguments
     * @return update rows
     */
    @SuppressWarnings({ "rawtypes", "unchecked" })
    public int update(String sql, Map args) {
        return getSimpleJdbcTemplate().update(sql, args);
    }

    /**
     * Update Table
     *
     * @param sql SQL
     * @param args Arguments
     * @param types Types
     * @return update rows
     */
    @SuppressWarnings("rawtypes")
    public int update(String sql, Map args, int[] types) {
        return getSimpleJdbcTemplate().update(sql, args, types);
    }

    /**
     * Update Table
     *
     * @param sql SQL
     * @param args Arguments
     * @return update rows
     */
    public int update(String sql, Object... args) {
        return getSimpleJdbcTemplate().update(sql, args);
    }


/*    *//**
     * Query For Page
     *
     * @param sql SQL
     * @param args Arguments
     * @param curPage Current Page
     * @param clazz Class
     * @return Page
     *//*
    @SuppressWarnings("rawtypes")
    public Page queryForPage(String sql, Class clazz, String curPage, Map args) {
        // do Query
        String finalSql = StringUtil.cnvtConutSql(sql);
        int totalRows = queryForInt(finalSql, args);
        if (totalRows == 0) {
            return Page.getDefault();
        }

        // Get Page Number.
        int pageNum = reCountPageNo(totalRows, curPage);

        finalSql = StringUtil.cnvtPageSql(sql, pageNum, SysConst.PER_PAGE_SIZE);
        // Execute Query
        List rList = queryForList(finalSql, clazz, args);

        // OUT >>>
        return new Page(rList, totalRows, pageNum);
    }


    *//**
     * ReCount Page Number.
     *
     * @param totalRows Total Rows
     * @param curPage Current Page.
     * @return Page Number.
     *//*
    private int reCountPageNo(int totalRows, String curPage) {
        int pageNum = 1;
        if (!StringUtil.isEmpty(curPage)) {
            pageNum = Integer.parseInt(curPage);
        }

        // Max Page No by total rows.
        int tPageNum = 0;
        if (totalRows % SysConst.PER_PAGE_SIZE == 0) {
            tPageNum = totalRows / SysConst.PER_PAGE_SIZE;
        } else {
            tPageNum = totalRows / SysConst.PER_PAGE_SIZE + 1;
        }

        // OUT
        return (pageNum < tPageNum) ? pageNum : tPageNum;
    }


    *//**
     * Query For Page
     *
     * @param sql SQL
     * @param type Class
     * @param curPage Current Page.
     * @param args Arguments
     * @return Page
     *//*
    @SuppressWarnings("rawtypes")
    public Page queryForPage(String sql, Class type, String curPage, Object... args) {
        // do Query
        String finalSql = StringUtil.cnvtConutSql(sql);
        int totalRows = queryForInt(finalSql, args);
        if (totalRows == 0) {
            return Page.getDefault();
        }

        // Get Page Number.
        int pageNum = reCountPageNo(totalRows, curPage);

        finalSql = StringUtil.cnvtPageSql(sql, pageNum, SysConst.PER_PAGE_SIZE);
        // Execute Query
        List rList = queryForList(finalSql, type, args);

        // OUT >>>
        return new Page(rList, totalRows, pageNum);
    }*/

    /**
     * Query for List
     *
     * @param sql SQL
     * @param args Arguments
     * @return List
     */
    @SuppressWarnings({ "rawtypes", "unchecked" })
    public List<Map<String, Object>> queryForList(String sql, Object... args) {
        // Execute Query
        List rList = getSimpleJdbcTemplate().queryForList(sql, args);
        // OUT >>>
        return cnvList(rList, null);
    }


    /**
     * Query for List
     *
     * @param sql SQL
     * @param args Arguments
     * @return List
     */
    @SuppressWarnings({ "rawtypes", "unchecked" })
    public List<Map<String, Object>> queryForList(String sql, Map args) {
        // Execute Query
        List rList = getSimpleJdbcTemplate().queryForList(sql, args);
        // OUT >>>
        return cnvList(rList, null);
    }

    /**
     * Query for List
     *
     * @param sql SQL
     * @param clazz Class
     * @param args Arguments
     * @return List
     */
    @SuppressWarnings("rawtypes")
    public List queryForList(String sql, Class clazz, Object... args) {
        // Execute Query
        List rList = getSimpleJdbcTemplate().queryForList(sql, args);
        // OUT >>>
        return cnvList(rList, clazz);
    }


    /**
     * Query for List
     *
     * @param sql SQL
     * @param clazz Class
     * @param args Arguments
     * @return list
     */
    @SuppressWarnings({ "rawtypes", "unchecked" })
    public List queryForList(String sql, Class clazz, Map args) {
        // Execute Query
        List rList = getSimpleJdbcTemplate().queryForList(sql, args);
        // OUT >>>
        return cnvList(rList, clazz);
    }


    /**
     * Convert List
     *
     * @param rList Result List
     * @param clazz Class
     * @return List
     */
    @SuppressWarnings({ "rawtypes", "unchecked" })
    private List cnvList(List rList, Class clazz) {
        // Lower keys
        ConvertUtil.lowerListMapKeys(rList);
        // Empty List Or Return Map only
        if (ConvertUtil.isEmpty(rList) || clazz == null) {
            logger.debug("Convert List Not Execute by Using Raw type (Map Element)!");
            return rList;
        }

        List tList = new ArrayList();
        Object bean = null;
        for (Object o : rList) {
            bean = BeanUtil.newInstance(clazz);
            ConvertUtil.cnvMap2Bean(bean, (Map) o);
            tList.add(bean);
        }
        // Bean List OUT >>>
        return tList;
    }
}
